package vzaar

import com.vzaar.transport.httpclient4.HttpClientTransportFactory;

/**
 * Transport response object. This encapsulates the HTTP status code and 
 * line as well as the response input stream.
 * 
 * @param statusCode the HTTP status code
 * @param statusLine the HTTP status line
 * @param response the response stream
 * 
 * @author Marc G. Smith
 */
class VzaarTransportResponse(
	val statusCode:Int, 
    val statusLine:String, 
    val response:java.io.InputStream) 

/**
 * Transport object to create transport based ona default factory. Changing
 * the defaultFactory will result in the new transport being used on with
 * new instances of Vzaar classes.
 * 
 * @author Marc G. Smith
 */
object VzaarTransport {
	var defaultFactory:VzaarTransportFactory = new JavaTransportFactoryBridge(new HttpClientTransportFactory());
	def create() = defaultFactory.create()
}

/**
 * Trait for handling the transport to <a href="http://vzzar.com">vzaar.com</a>. 
 * If you want to use a custom HTTP client or roll your own then this trait
 * needs to be implemented and registered with the VzaarTransport object.
 *  
 * @author Marc G. Smith
 */
trait VzaarTransport 
{
	/**
	 * Set the base API URL, such as http://vzaar.com/api/
	 * 
	 * @param url the base API URL
	 */
	def setUrl(url:String)
 
	/**
	 * Send any get request. If OAuth credentials have been added then OAuth
	 * authentication headers should be sent with each request.
	 * 
	 * @param uri the method URI
	 * @param parameters request parameters.
	 */
	def sendGetRequest(uri:String, parameters:Map[String,String]): VzaarTransportResponse
 
 	/**
	 * Send any post request. If OAuth credentials have been added then OAuth
	 * authentication headers are sent.
	 * 
	 * @param uri the method URI
	 * @param parameters request parameters
	 * @return the call response 
	 */
	def sendPostRequest(uri:String, parameters:Map[String,String]): VzaarTransportResponse 

	/**
	 * Send a post request with an XML body. If OAuth credentials have been 
	 * added then OAuth authentication headers are sent.
	 * 
	 * @param uri the method URI
	 * @param xml the XML content for the body of the request
	 * @return the call response 
	 */
	def sendPostXmlRequest(uri:String, xml:String): VzaarTransportResponse
 
	/**
	 * Set the OAuth 2 party tokens. If these are supplied then all calls to
	 * <a href="http://vzaar.com/">vzaar.com</a> will send OAuth credentials.
	 * 
	 * @param token the users login name
	 * @param secret the secret token supplied by vzaar
	 */
	def setOAuthTokens(token:String, secret:String)
 
	/**
	 * Upload a file to S3. This method doesn't use OAuth. If the callback is
	 * not null then the method should send progress reports to the callback.
	 * There is no need to call the error or complete calls on the callback
	 * as these are done by the Vzaar calling class.
	 *
	 * @param url The full url to the S3 bucket
	 * @param parameters the query parameters to send
	 * @param file the file to upload
	 * @param callback the callback to register for updates or null if not
	 *  required
	 * @return the call response 
	 */
	def uploadToS3(url:String, parameters:Map[String, String], file:java.io.File, callback:UploadProgressCallback): VzaarTransportResponse
 
	/**
	 * Add debugging output. Set to null to stop debugging.
	 * 
	 * @param out the output stream to send debug output to.
	 */
	def setDebugStream(out:java.io.OutputStream);
}

/**
 * VzaarTransport factory trait. Implementing transports need to create a 
 * factory instance that implements the create() method.
 * 
 * @author Marc G. Smith
 */
trait VzaarTransportFactory {
	/**
	 * Create a transport instance.
	 * 
	 * @return a new transport instance
	 */
	def create():VzaarTransport;
}

